import G6 from "@antv/g6/build/g6";
import { uniqueId } from '@/utils'
import Shape from '@antv/g/src/shapes'

const customNode = {
  init() {
    G6.registerNode("customNode", {
      /**
       * 绘制节点方法
       * @param {Object} cfg - 节点的配置信息（包含样式、图片、文本、锚点等）
       * @param {Object} group - G6 的分组容器，用于添加图形元素
       * @returns {Object} shape - 返回主 shape 对象
       */
      draw(cfg, group) {
        let size = cfg.size;
        // 如果未传 size，使用默认尺寸 [170, 34]
        if(!size){
          size=[170,34]
        }
        // 必须为数字类型，否则 bbox 计算异常
        const width = parseInt(size[0]);
        const height = parseInt(size[1]);
        const color = cfg.color; // 侧边色条颜色
        // 计算偏移量，使节点居中
        const offsetX = -width / 2
        const offsetY = -height / 2
        // 主矩形 shape 的唯一 id
        const mainId = 'rect' + uniqueId()
        // 添加主矩形 shape，作为节点的主体
        const shape = group.addShape("rect", {
          attrs: {
            id: mainId,
            x: offsetX,
            y: offsetY,
            width: width,
            height: height,
            stroke: "#ced4d9", // 边框色
            fill: '#fff',// 必须有 fill，否则无法触发事件
            radius: 4 // 圆角
          }
        });
        // 添加左侧色条
        group.addShape("rect", {
          attrs: {
            x: offsetX,
            y: offsetY,
            width: 4,
            height: height,
            fill: color, // 传入的颜色
            parent: mainId,
            radius: [4, 0, 0, 4] // 只左侧圆角
          }
        });
        // 添加左侧图标图片
        group.addShape("image", {
          attrs: {
            x: offsetX + 16,
            y: offsetY + 8,
            width: 20,
            height: 16,
            img: cfg.image, // 传入的图片地址
            parent: mainId
          }
        });
        // 添加右侧状态图片
        group.addShape("image", {
          attrs: {
            x: offsetX + width - 32,
            y: offsetY + 8,
            width: 16,
            height: 16,
            parent: mainId,
            img: cfg.stateImage // 传入的状态图片
          }
        });
        // 如果有背景图片，添加并裁剪为圆角矩形
        if(cfg.backImage){
          // 创建裁剪区域
          const clip = new Shape.Rect({
            attrs: {
              x: offsetX,
              y: offsetY,
              width: width,
              height: height,
              fill:'#fff',
              radius: 4
            }
        });
          // 添加背景图片并应用裁剪
          group.addShape("image", {
            attrs: {
              x: offsetX,
              y: offsetY,
              width: width,
              height: height,
              img: cfg.backImage,
              clip: clip
            }
          });
        }
        // 添加节点文本标签
        if (cfg.label) {
           group.addShape("text", {
            attrs: {
              id: 'label' + uniqueId(),
              x: offsetX + width / 2,
              y: offsetY + height / 2,
              textAlign: "center", // 居中对齐
              textBaseline: "middle", // 垂直居中
              text: cfg.label, // 文本内容
              parent: mainId,
              fill: "#565758" // 字体颜色
            }
          });
        }
        // 添加输入锚点（inPoints）
        if (cfg.inPoints) {
          for (let i = 0; i < cfg.inPoints.length; i++) {
            let x,
              y = 0;
            // 0 表示顶部，1 表示底部
            if (cfg.inPoints[i][0] === 0) {
              y = 0;
            } else {
              y = height;
            }
            x = width * cfg.inPoints[i][1]; // 按比例计算横坐标
            const id = 'circle' + uniqueId()
            // 外层透明大圆，便于交互
            group.addShape("circle", {
              attrs: {
                id: 'circle' + uniqueId(),
                parent: id,
                x: x + offsetX,
                y: y + offsetY,
                r: 10, // 半径较大
                isInPointOut: true, // 标记为输入锚点外圈
                fill: "#1890ff",
                opacity: 0 // 默认透明
              }
            });
            // 内层小圆，实际锚点
            group.addShape("circle", {
              attrs: {
                id: id,
                x: x + offsetX,
                y: y + offsetY,
                r: 3, // 半径较小
                isInPoint: true, // 标记为输入锚点
                fill: "#fff",
                stroke: "#1890ff",
                opacity: 0 // 默认透明
              }
            });
          }
        }
        // 添加输出锚点（outPoints）
        if (cfg.outPoints) {
          for (let i = 0; i < cfg.outPoints.length; i++) {
            let x,
              y = 0;
            // 0 表示顶部，1 表示底部
            if (cfg.outPoints[i][0] === 0) {
              y = 0;
            } else {
              y = height;
            }
            x = width * cfg.outPoints[i][1]; // 按比例计算横坐标
            const id = 'circle' + uniqueId()
            // 外层透明大圆，便于交互
            group.addShape("circle", {
              attrs: {
                id: 'circle' + uniqueId(),
                parent: id,
                x: x + offsetX,
                y: y + offsetY,
                r: 10,
                isOutPointOut: true, // 标记为输出锚点外圈
                fill: "#1890ff",
                opacity: 0// 默認0 需要时可改为0.3
              }
            });
            // 内层小圆，实际锚点
            group.addShape("circle", {
              attrs: {
                id: id,
                x: x + offsetX,
                y: y + offsetY,
                r: 3,
                isOutPoint: true, // 标记为输出锚点
                fill: "#fff",
                stroke: "#1890ff",
                opacity: 0
              }
            });
          }
        }
        // group.sort() // 可选：对子元素排序
        // 返回主 shape
        return shape;
      },
      /**
       * 设置节点状态（如选中、悬浮等）
       * @param {string} name - 状态名（如 'selected', 'hover'）
       * @param {boolean} value - 状态值
       * @param {Object} item - 当前节点实例
       */
      setState(name, value, item) {
        const group = item.getContainer(); // 获取节点的分组容器
        const shape = group.get("children")[0]; // 获取主 shape（顺序与 draw 保持一致）

        // 找到所有属于主 shape 的子元素
        const children = group.findAll(g => {
          return g._attrs.parent === shape._attrs.id
        });
        // 找到所有锚点小圆
        const circles = group.findAll(circle => {
          return circle._attrs.isInPoint || circle._attrs.isOutPoint;
        });
        // 选中/悬浮样式
        const selectStyles = () => {
          shape.attr("fill", "#f3f9ff"); // 改变填充色
          shape.attr("stroke", "#6ab7ff"); // 改变边框色
          shape.attr("cursor", "move"); // 鼠标样式
          children.forEach(child => {
            child.attr("cursor", "move");
          });
          circles.forEach(circle => {
            circle.attr('opacity', 1) // 显示锚点
          })
        };
        // 取消选中/悬浮样式
        const unSelectStyles = () => {
          shape.attr("fill", "#fff");
          shape.attr("stroke", "#ced4d9");
          circles.forEach(circle => {
            circle.attr('opacity', 0) // 隐藏锚点
          })
        };
        // 根据状态名和状态值切换样式
        switch (name) {
          case "selected":
          case "hover":
            if (value) {
              selectStyles()
            } else {
              unSelectStyles()
            }
            break;
        }
      }
    });
  }
}

export default customNode
